package com.kha.listone.screen.single;

import java.util.Calendar;
import java.util.Date;

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.DateField;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.ItemCommandListener;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;

import com.kha.listone.ListOne;
import com.kha.listone.common.SingleScreen;
import com.kha.listone.common.model.TaskModel;
import com.kha.listone.util.Commands;
import com.kha.listone.util.Globals;
import com.kha.listone.util.operation.Operation;
import com.kha.listone.util.xml.TasksXMLGenerator;

public class AddTaskScreen extends SingleScreen implements ItemCommandListener {

	private TextField taskNameField;
	private DateField dueDayField;
	private DateField deadlineDateField;
	private StringItem recurrenceTypeChoice;
	private ChoiceGroup recurrenceDateOfWeekChoice;
	private TextField taskNoteBox;
	private TextField taskTagsBox;
	private ChoiceGroup importantChoice;

	private Command cmdOnce, cmdDaily, cmdWeekly;

	public AddTaskScreen(ListOne midlet, String title) {

		super(midlet, title);

	}

	protected void initScreen() {

		cmdOnce = new Command("Once", Command.SCREEN, 1);
		cmdDaily = new Command("Daily", Command.SCREEN, 1);
		cmdWeekly = new Command("Weekly", Command.SCREEN, 1);

		dueDayField = new DateField("Start", DateField.DATE_TIME);
		deadlineDateField = new DateField("Deadline", DateField.DATE_TIME);

		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		dueDayField.setDate(cal.getTime());
		deadlineDateField.setDate(new Date(cal.getTime().getTime() + 1000 * 60
				* 60 * 24));

		recurrenceTypeChoice = new StringItem("Repeat", "Once", Item.BUTTON);
		recurrenceTypeChoice.setDefaultCommand(Commands.CHANGE_FORM);
		recurrenceTypeChoice.setItemCommandListener(this);

		recurrenceDateOfWeekChoice = new ChoiceGroup("Repeat day of week",
				ChoiceGroup.MULTIPLE);

		taskNoteBox = new TextField("Note", "", 500, 0);

		taskTagsBox = new TextField("Tags (seperate by ,)", "", 500, 0);

		importantChoice = new ChoiceGroup("Important", ChoiceGroup.POPUP);

		taskNameField = new TextField("Task name", "", 100, 0);

		recurrenceDateOfWeekChoice.append("Sunday", null);
		recurrenceDateOfWeekChoice.append("Monday", null);
		recurrenceDateOfWeekChoice.append("Tuesday", null);
		recurrenceDateOfWeekChoice.append("Wednesday", null);
		recurrenceDateOfWeekChoice.append("Thursday", null);
		recurrenceDateOfWeekChoice.append("Friday", null);
		recurrenceDateOfWeekChoice.append("Saturday", null);

		importantChoice.append("Low", null);
		importantChoice.append("Normal", null);
		importantChoice.append("Low", null);
		importantChoice.setSelectedIndex(1, true);

		this.append(taskNameField);
		this.append(dueDayField);
		this.append(recurrenceTypeChoice);
		this.append(deadlineDateField);
		this.append(importantChoice);
		this.append(taskNoteBox);
		this.append(taskTagsBox);

		this.addCommand(Commands.OK);
		enququeOperation.start();
		super.initScreen();
	}

	public void commandAction(Command c, Displayable d) {
		if (c == Commands.OK) {

			// Check valid
			// Task name
			if (taskNameField.getString().trim().equals("")) {

				showMessage("Error", "Please name your task", AlertType.ERROR,
						null);
				return;
			}
			// Recurrence == Once => Check Due Date <= DeadlineDate

			if (recurrenceTypeChoice.getText() == "Once") {
				if (dueDayField.getDate().getTime() >= deadlineDateField
						.getDate().getTime()) {
					showMessage("Error", "Please set deadline date correctly",
							AlertType.ERROR, null);
					return;
				}
			}
			// Recurrence == Daily => nothing
			// Recurrence == Weekly => Check Week Date <> {}
			if (recurrenceTypeChoice.getText() == "Weekly") {
				boolean valid = false;
				for (int i = 0; i < 7; i++) {
					if (recurrenceDateOfWeekChoice.isSelected(i)) {
						valid = true;
						break;
					}
				}
				if (!valid) {
					showMessage("Error",
							"Please select at least one day of week",
							AlertType.ERROR, null);
					return;
				}
			}

			// Add Task to list and generate XML

			TaskModel task = new TaskModel();

			task.setTaskName(taskNameField.getString().trim());
			task.setDueDate(dueDayField.getDate());
			task.setDone(TaskModel.UNDONE);

			task.setImportantRate((short) importantChoice.getSelectedIndex());

			if (recurrenceTypeChoice.getText() == "Daily") {
				task.setRecurrenceStatus(TaskModel.RECURRENCE_DAILY);
			} else if (recurrenceTypeChoice.getText() == "Weekly") {
				task.setRecurrenceStatus(TaskModel.RECURRENCE_WEEKLY);
				String temp = "";

				for (int i = 0; i < 7; i++) {
					if (recurrenceDateOfWeekChoice.isSelected(i)) {
						temp += String.valueOf(i);
					}
				}
				task.setDateRecurrence(temp);
			} else {
				task.setRecurrenceStatus(TaskModel.RECURRENCE_ONCE);
				task.setDeadlineDate(deadlineDateField.getDate());
			}

			task.setTaskNote(taskNoteBox.getString().trim());
			task.setTaskTags(taskTagsBox.getString().trim());

			Globals.taskList.insertElementAt(task, 0);
			showMessage("ListOne", "Add new task successfully",
					AlertType.CONFIRMATION, null);

			enququeOperation.enqueue(new TasksXMLGenerator());
			enququeOperation.enqueue(new PostWriteXML(this));
			enququeOperation.restart();
			
		}

		if (c == cmdOnce) {
			deleteAll();
			this.append(taskNameField);
			this.append(dueDayField);
			this.append(recurrenceTypeChoice);
			this.append(deadlineDateField);
			this.append(importantChoice);
			this.append(taskNoteBox);
			this.append(taskTagsBox);

			mainMIDlet.showDisplay(this);

			recurrenceTypeChoice.setText("Once");
		}

		if (c == cmdDaily) {
			deleteAll();
			this.append(taskNameField);
			this.append(dueDayField);
			this.append(recurrenceTypeChoice);
			this.append(importantChoice);
			this.append(taskNoteBox);
			this.append(taskTagsBox);
			mainMIDlet.showDisplay(this);
			recurrenceTypeChoice.setText("Daily");
		}

		if (c == cmdWeekly) {
			deleteAll();
			this.append(taskNameField);
			this.append(dueDayField);
			this.append(recurrenceTypeChoice);
			this.append(recurrenceDateOfWeekChoice);
			this.append(importantChoice);
			this.append(taskNoteBox);
			this.append(taskTagsBox);
			mainMIDlet.showDisplay(this);
			recurrenceTypeChoice.setText("Weekly");
		}

		super.commandAction(c, d);
	}

	public void refresh() {
		this.deleteAll();

		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		dueDayField.setDate(cal.getTime());
		deadlineDateField.setDate(new Date(cal.getTime().getTime() + 1000 * 60
				* 60 * 24));

		this.append(taskNameField);
		this.append(dueDayField);
		this.append(recurrenceTypeChoice);
		this.append(deadlineDateField);
		this.append(importantChoice);
		this.append(taskNoteBox);
		this.append(taskTagsBox);

		taskNameField.setString("");
		taskNoteBox.setString("");
		taskTagsBox.setString("");

		recurrenceTypeChoice.setText("Once");
		recurrenceDateOfWeekChoice.setSelectedFlags(new boolean[] { false,
				false, false, false, false, false, false });
		importantChoice.setSelectedIndex(1, true);

		super.refresh();
	}

	public void commandAction(Command c, Item item) {
		if (c == Commands.CHANGE_FORM) {
			if (item == recurrenceTypeChoice) {
				Alert alert = new Alert("Add new task", "Repeat type:", null,
						AlertType.INFO);
				alert.addCommand(cmdOnce);
				alert.addCommand(cmdDaily);
				alert.addCommand(cmdWeekly);
				alert.setCommandListener(this);
				alert.setCommandListener(this);

				mainMIDlet.showDisplay(alert);
			}
		}
	}

	private class PostWriteXML implements Operation {

		private AddTaskScreen screen;

		public PostWriteXML(AddTaskScreen screen) {
			this.screen = screen;
		}

		public void execute() {
			synchronized (screen) {
				screen.mainMIDlet.back();
			}

		}

	}

}
